home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcr / pcr4_4.lha / DIST / debugnub / RDTRuntime.c < prev   
C/C++ Source or Header  |  1992-02-18  |  13KB  |  610 lines

  1. /* begincopyright
  2.   Copyright (c) 1988 Xerox Corporation. All rights reserved.
  3.   Use and copying of this software and preparation of derivative works based
  4.   upon this software are permitted. Any distribution of this software or
  5.   derivative works must comply with all applicable United States export
  6.   control laws. This software is made available AS IS, and Xerox Corporation
  7.   makes no warranty about the software, its performance or its conformity to
  8.   any specification. Any person obtaining a copy of this software is requested
  9.   to send their name and post office or electronic mail address to:
  10.     PCR Coordinator
  11.     Xerox PARC
  12.     3333 Coyote Hill Rd.
  13.     Palo Alto, CA 94304
  14.   endcopyright */
  15.  
  16. /*
  17.  * RDTRuntime.c
  18.  *
  19.  * Runtime support for remote debug tool.
  20.  *
  21.  * Demers, February 19, 1990 9:53:45 am PST
  22.  */
  23.  
  24. #include "xr/BasicTypes.h"
  25. #include "xr/Errno.h"
  26. #include "xr/CirioNubTypes.h"
  27. #include "xr/CirioNubProtocol.h"
  28. #include "xr/RDTRuntime.h"
  29.  
  30. #include <sys/socket.h>
  31. #include <netinet/in.h>
  32. #include <netinet/tcp.h>
  33. #include <netdb.h>
  34.  
  35.  
  36. /*
  37.     read/write without returning short result
  38. */
  39.  
  40.  
  41. static CirioNubRetCode
  42. RDT_DoIOUntilDone(fd, in, buf, nBytes)
  43.     int fd;
  44.     bool in;
  45.     char *buf;
  46.     int nBytes;
  47. {
  48.     int ans;
  49.     CirioNubRetCode retCode = cnrc_comm;
  50.  
  51.     for(;;) {
  52.         if( fd < 0 ) break;
  53.         ans = (in ? read(fd, buf, nBytes) : write(fd, buf, nBytes));
  54.         if( ans < 0 ) { ans = (-errno); break; }
  55.         if( (ans == 0) && in ) break;
  56.         nBytes -= ans;
  57.         buf += ans;
  58.         if( nBytes <= 0 ) { retCode = cnrc_ok; break; }
  59.     }
  60.     return retCode;
  61. }
  62.  
  63.  
  64. #define readall(fd, buf, nBytes) \
  65.     RDT_DoIOUntilDone((fd), TRUE, (buf), (nBytes))
  66.  
  67. #define writeall(fd, buf, nBytes) \
  68.     RDT_DoIOUntilDone((fd), FALSE, (buf), (nBytes))
  69.  
  70.  
  71.  
  72. /*
  73.  * Global state
  74.  */
  75.  
  76. int RDT_rpcFD = -1;
  77.  
  78. int RDT_dbPrintCtl = 1;
  79.     /* positive disables until counts down to 1 */
  80.     /* negative enables until counts up to 0 */
  81.  
  82.  
  83. /*
  84.  * Debugging messages
  85.  */
  86.  
  87. void RDT_Msg(fmt, x1, x2, x3, x4)
  88.     char *fmt;
  89.     int x1, x2, x3, x4;
  90. {
  91.     char buf[1024];
  92.  
  93.     sprintf(buf, fmt, x1, x2, x3, x4);
  94.     (void)RDT_DoIOUntilDone(1, FALSE, buf, strlen(buf));
  95. }
  96.  
  97. void RDT_DBMsg(fmt, x1, x2, x3, x4)
  98.     char *fmt;
  99.     int x1, x2, x3, x4;
  100. {
  101.     char buf[1024];
  102.  
  103.     int ctl = RDT_dbPrintCtl;
  104.     if( (ctl < 0) || (ctl == 1) ) {
  105.         sprintf(buf, fmt, x1, x2, x3, x4);
  106.         (void)RDT_DoIOUntilDone(1, FALSE, buf, strlen(buf));
  107.     }
  108.     if( ctl < 0 ) {
  109.         ctl++;
  110.     } else if( ctl > 1 ) {
  111.         ctl--;;
  112.     }
  113.     RDT_dbPrintCtl = ctl;
  114. }
  115.  
  116.  
  117. /*
  118.  * Marshalling stuff
  119.  */
  120.  
  121.  
  122. /*
  123.  * Send data with type info
  124.  */
  125.  
  126.  
  127. static CirioNubRetCode
  128. RDT_Put32Inner(n, tag)
  129.     unsigned n;
  130.     enum CirioNubTag tag;
  131. {
  132.     struct {
  133.     struct CirioNubWrapper w;
  134.     net_long x;
  135.     } buf;
  136.  
  137.     buf.w.cnw_tag = htons(((short)(tag)));
  138.     buf.w.cnw_len = htons( (sizeof n) );
  139.     buf.x = htonl(n);
  140.     return writeall(RDT_rpcFD, &buf, (sizeof buf));
  141. }
  142.  
  143.  
  144. CirioNubRetCode
  145. RDT_PutRetCode(c)
  146.     CirioNubRetCode c;
  147. {
  148.     return RDT_Put32Inner(((unsigned)(c)), cnt_retCode);
  149. }
  150.  
  151. CirioNubRetCode
  152. RDT_PutProcID(id)
  153.     unsigned id;
  154. {
  155.     return RDT_Put32Inner(((unsigned)(id)), cnt_procID);
  156. }
  157.  
  158.  
  159.  
  160. CirioNubRetCode
  161. RDT_PutCard32(n)
  162.     unsigned n;
  163. {
  164.     return RDT_Put32Inner(((unsigned)(n)), cnt_card32);
  165. }
  166.  
  167.  
  168. CirioNubRetCode
  169. RDT_PutInt32(n)
  170.     int n;
  171. {
  172.     return RDT_Put32Inner(((unsigned)(n)), cnt_int32);
  173. }
  174.  
  175.  
  176. static CirioNubRetCode
  177. RDT_PutBlock8Inner(b, len, tag)
  178.     char *b;
  179.     int len;
  180.     enum CirioNubTag tag;
  181. {
  182.     struct CirioNubWrapper w;
  183.     CirioNubRetCode ans;
  184.  
  185.     w.cnw_tag = htons(((short)(tag)));
  186.     w.cnw_len = htons(len);
  187.     if( (ans = writeall(RDT_rpcFD, &w, (sizeof w))) != cnrc_ok ) {
  188.     return(ans);
  189.     }
  190.     if( len == 0 ) return(cnrc_ok);
  191.     if( (ans = writeall(RDT_rpcFD, b, len)) != cnrc_ok ) {
  192.     return(ans);
  193.     }
  194.     if( len & 03 ) {
  195.      int slop = 4 - (len & 03);
  196.      int zero = 0;
  197.      if( (ans = writeall(RDT_rpcFD, &zero, slop)) != cnrc_ok ) {
  198.         return(ans);
  199.     }
  200.     }
  201.     return(cnrc_ok);
  202. }
  203.  
  204.  
  205. CirioNubRetCode
  206. RDT_PutString(s)
  207.     char *s;
  208. {
  209.     return( RDT_PutBlock8Inner(s, strlen(s), cnt_string) );
  210. }
  211.  
  212.  
  213. CirioNubRetCode
  214. RDT_PutBlock8(b, len)
  215.     char *b;
  216.     int len;
  217. {
  218.     return( RDT_PutBlock8Inner(b, len, cnt_block8) );
  219. }
  220.  
  221.  
  222. CirioNubRetCode
  223. RDT_PutBlock16(b, len)
  224.     short *b;
  225.     int len;
  226. {
  227.     struct CirioNubWrapper w;
  228.     CirioNubRetCode ans;
  229.     int zero = 0;
  230.  
  231.     b = (short *)(((unsigned)(b)) & (~01));
  232.     len = (len + 1) & (~01);
  233.     w.cnw_tag = htons(cnt_block16);
  234.     w.cnw_len = htons(len);
  235.     ans = writeall(RDT_rpcFD, &w, (sizeof w));
  236.     if( (ans = writeall(RDT_rpcFD, &w, (sizeof w))) != cnrc_ok ) {
  237.     return(ans);
  238.     }
  239.     if( len == 0 ) return(cnrc_ok);
  240.     if( htons(1) != 1 ) {
  241.     int cnt = len;
  242.     short *p = b;
  243.     while( cnt > 0 ) { *p = htons(*p); p++; cnt-= 2; }
  244.     }
  245.     if( (ans = writeall(RDT_rpcFD, b, len)) == cnrc_ok ) {
  246.     if( (len & 03) != 0 ) {
  247.         ans = writeall(RDT_rpcFD, &zero, 2);
  248.     }
  249.     }
  250.     if( htons(1) != 1 ) {
  251.     int cnt = len;
  252.     short *p = b;
  253.     while( cnt > 0 ) { *p = ntohs(*p); p++; cnt-= 2; }
  254.     }
  255.     return( ans );
  256. }
  257.  
  258.  
  259. CirioNubRetCode
  260. RDT_PutBlock32(b, len)
  261.     long *b;
  262.     int len;
  263. {
  264.     struct CirioNubWrapper w;
  265.     CirioNubRetCode ans;
  266.  
  267.     b = (long *)(((unsigned)(b)) & (~03));
  268.     len = (len + 3) & (~03);
  269.     w.cnw_tag = htons(cnt_block32);
  270.     w.cnw_len = htons(len);
  271.     if( (ans = writeall(RDT_rpcFD, &w, (sizeof w))) != cnrc_ok ) {
  272.     return(ans);
  273.     }
  274.     if( len == 0 ) return(cnrc_ok);
  275.     if( htons(1) != 1 ) {
  276.     int cnt = len;
  277.     long *p = b;
  278.     while( cnt > 0 ) { *p = htonl(*p); p++; cnt-= 4; }
  279.     }
  280.     ans = writeall(RDT_rpcFD, b, len);
  281.     if( htons(1) != 1 ) {
  282.     int cnt = len;
  283.     long *p = b;
  284.     while( cnt > 0 ) { *p = ntohl(*p); p++; cnt-= 4; }
  285.     }
  286.     return( ans );
  287. }
  288.  
  289.  
  290.  
  291.  
  292.  
  293. static CirioNubRetCode
  294. RDT_GetCard32(b)
  295.     unsigned *b;
  296. {
  297.     CirioNubRetCode ans;
  298.     unsigned buf;
  299.  
  300.     if( (ans = readall(RDT_rpcFD, &buf, (sizeof buf))) != cnrc_ok )
  301.     return(ans);
  302.     *b = ntohl(buf);
  303.     return(cnrc_ok);
  304. }
  305.  
  306.  
  307. #define RDT_GetInt32(b)    RDT_GetCard32( ((unsigned *)(b)) )
  308.  
  309. #define RDT_GetRetCode(b) RDT_GetCard32( ((unsigned *)(b)) )
  310.  
  311. #define RDT_GetProcID(b) RDT_GetCard32( ((unsigned *)(b)) )
  312.  
  313.  
  314. /* all lengths below are rounded up to full 32-bit words */
  315.  
  316. static CirioNubRetCode
  317. RDT_GetBlock8(b, len)
  318.     char *b;
  319.     int len;
  320. {
  321.     len = (len + 3) & (~03);
  322.     return( readall(RDT_rpcFD, b, len) );
  323. }
  324.  
  325.  
  326. static CirioNubRetCode
  327. RDT_GetBlock16(b, len)
  328.     short *b;
  329.     int len;
  330. {
  331.     CirioNubRetCode ans;
  332.  
  333.     if( len == 0 ) return(cnrc_ok);
  334.     b = (short *)(((unsigned)(b)) & (~01));
  335.     len = (len + 3) & (~03);
  336.     if( (ans = readall(RDT_rpcFD, b, len)) != cnrc_ok ) return(ans);
  337.     if( htons(1) != 1 ) {
  338.     while( len > 0 ) { *b = ntohs(*b); b++; len -= 2; }
  339.     }
  340.     return(cnrc_ok);
  341. }
  342.  
  343.  
  344. static CirioNubRetCode
  345. RDT_GetBlock32(b, len)
  346.     long *b;
  347.     int len;
  348. {
  349.     CirioNubRetCode ans;
  350.  
  351.     if( len == 0 ) return(cnrc_ok);
  352.     b = (long *)(((unsigned)(b)) & (~03));
  353.     len = (len + 3) & (~03);
  354.     if( (ans = readall(RDT_rpcFD, b, len)) != cnrc_ok ) return(ans);
  355.     if( htonl(1) != 1 ) {
  356.     while( len > 0 ) { *b = ntohl(*b); b++; len -= 4; }
  357.     }
  358.     return(cnrc_ok);
  359. }
  360.  
  361.  
  362.  
  363.  
  364. CirioNubRetCode
  365. RDT_ReadReply(buffer, bufferBytes, argcPtr)
  366.     unsigned *buffer;
  367.     unsigned bufferBytes;
  368.     unsigned *argcPtr;
  369. {
  370.     CirioNubRetCode ans;
  371.     CirioNubRetCode retCode;
  372.     struct CirioNubWrapper w;
  373.     int len, roundedLen, roundedLenWithNull;
  374.     char *p;
  375.     unsigned *argp;
  376.  
  377. #   define NEEDSPACE(n) \
  378.     if ( (((char *)(argp)) + (n)) > p ) { ans = cnrc_space; goto Out; }
  379.  
  380.  
  381.     *argcPtr = 0; /* default */
  382.     argp = buffer;
  383.     p = ((char *)(buffer)) + bufferBytes;
  384.     for(;;) {
  385.     if( (ans = readall(RDT_rpcFD, &w, (sizeof w))) != cnrc_ok ) {
  386.             RDT_Msg("Bad read %d\n", ans);
  387.         goto Out;
  388.     }
  389.     len = (int)(ntohs(w.cnw_len));
  390.     roundedLen = (len + 03) & (~03);
  391.     switch( ntohs(w.cnw_tag) ) {
  392.         case cnt_retCode:
  393.                 if( (ans = RDT_GetRetCode(&retCode)) == cnrc_ok ) {
  394.                     (*argcPtr) = (argp - buffer);
  395.         }
  396.         goto Out;
  397.         case cnt_card32:
  398.         NEEDSPACE((sizeof *argp));
  399.         if( (ans = RDT_GetCard32(argp)) != cnrc_ok ) goto Out;
  400.         argp++;
  401.         break;
  402.         case cnt_int32:
  403.         NEEDSPACE((sizeof *argp));
  404.         if( (ans = RDT_GetInt32(argp)) != cnrc_ok ) goto Out;
  405.         argp++;
  406.         break;
  407.         case cnt_string:
  408.         roundedLenWithNull = (len + 04) & (~03);
  409.         NEEDSPACE(roundedLenWithNull+(sizeof *argp));
  410.         p -= roundedLenWithNull;
  411.         if( (ans = RDT_GetBlock8(p, roundedLen)) != cnrc_ok )
  412.             goto Out;
  413.         p[len] = 0;
  414.         *argp++ = (unsigned)(p);
  415.         break;
  416.         case cnt_block8:
  417.         NEEDSPACE(roundedLen+2*(sizeof *argp));
  418.         p -= roundedLen;
  419.         if( (ans = RDT_GetBlock8(p, roundedLen)) != cnrc_ok )
  420.             goto Out;
  421.         *argp++ = len;
  422.         *argp++ = (unsigned)(p);
  423.         break;
  424.         case cnt_block16:
  425.         NEEDSPACE(roundedLen+2*(sizeof *argp));
  426.         p -= roundedLen;
  427.         if( (ans = RDT_GetBlock16(p, roundedLen)) != cnrc_ok )
  428.             goto Out;
  429.         *argp++ = len;
  430.         *argp++ = (unsigned)(p);
  431.         break;
  432.         case cnt_block32:
  433.         NEEDSPACE(roundedLen+2*(sizeof *argp));
  434.         p -= roundedLen;
  435.         if( (ans = RDT_GetBlock32(p, roundedLen)) != cnrc_ok )
  436.             goto Out;
  437.         *argp++ = len;
  438.         *argp++ = (unsigned)(p);
  439.         break;
  440.         default:
  441.         ans = cnrc_protocol;
  442.         goto Out;
  443.     }
  444.     }
  445. Out:
  446.     if( ans >= cnrc_MUST_CLOSE_CONNECTION ) {
  447.         (void) RDT_Disconnect(FALSE);
  448.     }
  449.     return ans;
  450. }
  451. #undef NEEDSPACE
  452.  
  453.  
  454. CirioNubRetCode
  455. RDT_SendCall(procID)
  456.     unsigned procID;
  457. {
  458.     CirioNubRetCode ans;
  459.  
  460.     ans = RDT_PutProcID(procID);
  461.     if( ans >= cnrc_MUST_CLOSE_CONNECTION ) {
  462.         (void) RDT_Disconnect(FALSE);
  463.     }
  464.     return ans;
  465. }
  466.  
  467.  
  468. static int /* -err */
  469. RDT_ParseNumericAddressAndPort( ap, name, port )
  470.     struct sockaddr_in *ap;
  471.     char *name;
  472.     unsigned port;
  473. {
  474.     int i, j;
  475.     char c;
  476.     u_int v;
  477.     u_char b[4];
  478.     i = 0;
  479.     j = 0;
  480.     while ((c=name[i])!=0) {
  481.         v = 0;
  482.         if (c=='.') {return(-1);}
  483.         while ((c!='.')&&(c!=0)) {
  484.             if (c < '0') {return(-1);}
  485.             if (c > '9') {return(-1);}
  486.             v = (v * 10) + (c-'0');
  487.             if (v > 255) {return(-1);}
  488.             i=i+1;
  489.             c=name[i];
  490.         }
  491.         if (j>=4) {return(-1);}
  492.         b[j] = v;
  493.         j = j+1;
  494.         if (c!=0) {i=i+1;}
  495.     }
  496.     if( port == 0 ) port = CIRIO_NUB_LISTENER_PORT;
  497.     if (j!=4) {return(-1);}
  498.     bzero( ((char *)(ap)), (sizeof (*ap)) );
  499.     ap->sin_family = AF_INET;
  500.     ap->sin_port = port;
  501.     bcopy( b, ((char *)(&(ap->sin_addr))), 4);
  502.     return (0); /* success */
  503. }
  504.  
  505.  
  506. #ifdef UNDEFINED
  507. static int /* -err */
  508. RDT_ParseNameAndPort( ap, name, port )
  509.     struct sockaddr_in *ap;
  510.     char *name;
  511.     unsigned port;
  512. {
  513.     extern struct hostent *(gethostbyname());
  514.     extern char *(strrchr());
  515.     struct hostent *hep;
  516.     char *colonPtr;
  517.     int len, tPort;
  518.     int ans = 0;
  519.     char *fixedName = name;
  520.  
  521.     colonPtr = strrchr( name, ':' );
  522.     if( colonPtr != NIL ) {
  523.         len = (colonPtr - name);
  524.         fixedName = (char *) malloc(1+len);
  525.         (void) bcopy( name, fixedName, len);
  526.         fixedName[len] = 0;
  527.         tPort = atoi(&(colonPtr[1]));
  528.         if( tPort == -1 ) { ans = -1; goto Out; }
  529.         if( tPort > 0 ) port = ((unsigned)(tPort));
  530.     }
  531.     if( port == 0 ) port = CIRIO_NUB_LISTENER_PORT;
  532.     hep = gethostbyname(fixedName);
  533.     if( hep == 0 ) { ans = -2; goto Out; }
  534.     if( hep->h_addrtype != AF_INET ) { ans = -3; goto Out; }
  535.     bzero( ((char *)(ap)), (sizeof (*ap)) );
  536.     ap->sin_family = hep->h_addrtype;
  537.     ap->sin_port = ((u_short)(port));
  538.     bcopy( ((char *)(hep->h_addr)), ((char *)(&(ap->sin_addr))),
  539.             hep->h_length );
  540.   Out:
  541.     if( fixedName != name ) free(fixedName);
  542.     return ans;
  543. }
  544. #else
  545. static int /* -err */
  546. RDT_ParseNameAndPort( ap, name, port )
  547.     struct sockaddr_in *ap;
  548.     char *name;
  549.     unsigned port;
  550. {
  551.     extern struct hostent *(gethostbyname());
  552.     struct hostent *hep;
  553.     int tPort;
  554.     int ans = 0;
  555.  
  556.     if( port == 0 ) port = CIRIO_NUB_LISTENER_PORT;
  557.     hep = gethostbyname(name);
  558.     if( hep == 0 ) { ans = -2; goto Out; }
  559.     if( hep->h_addrtype != AF_INET ) { ans = -3; goto Out; }
  560.     bzero( ((char *)(ap)), (sizeof (*ap)) );
  561.     ap->sin_family = hep->h_addrtype;
  562.     ap->sin_port = ((u_short)(port));
  563.     bcopy( ((char *)(hep->h_addr)), ((char *)(&(ap->sin_addr))),
  564.             hep->h_length );
  565.   Out:
  566.     return ans;
  567. }
  568. #endif
  569.  
  570. CirioNubRetCode
  571. RDT_Connect(hostName, defaultPort)
  572.     char *hostName;
  573.     unsigned defaultPort;
  574. {
  575.     unsigned addrBuf[32];
  576.     struct sockaddr_in a;
  577.     int fd;
  578.     int ans;
  579.     int one = 1;
  580.  
  581.     if( (RDT_ParseNumericAddressAndPort(&a, hostName, defaultPort) < 0)
  582.             && (RDT_ParseNameAndPort(&a, hostName, defaultPort) < 0) ) {
  583.         return cnrc_badArgs;
  584.     }
  585.     fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  586.     if( fd < 0 )
  587.         return cnrc_comm;
  588.     ans = connect(fd, &a, (sizeof a));
  589.     if( ans < 0 ) {
  590.         (void)close(fd);
  591.         return cnrc_comm;
  592.     }
  593.     (void) setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, (sizeof one));
  594.     RDT_rpcFD = fd;
  595.     return cnrc_ok;
  596. }
  597.  
  598. CirioNubRetCode
  599. RDT_Disconnect( doAbort )
  600.     bool doAbort;
  601. {
  602.     if( RDT_rpcFD < 0 ) return cnrc_ok;
  603.     if( doAbort ) {
  604.         (void) shutdown(RDT_rpcFD);
  605.     }
  606.     (void) close(RDT_rpcFD);
  607.     RDT_rpcFD = -1;
  608.     return cnrc_ok;
  609. }
  610.